package main

import (
	"context"
	"encoding/json"
	"fmt"
	"game_server/config"
	"game_server/framework/connection"
	"game_server/framework/global"
	"game_server/framework/message"
	"game_server/framework/router"
	"game_server/game"
	"game_server/game/model"
	"game_server/handler/barrage"
	"game_server/handler/bet"
	"game_server/handler/change"
	"game_server/handler/heart"
	"game_server/handler/room"
	"game_server/handler/test"
	"game_server/proto"
	"game_server/tool"
	"net/http"
	"runtime"
	"time"

	"github.com/duke-git/lancet/v2/convertor"
	"github.com/gorilla/websocket"
	"github.com/spf13/viper"
)

func main() {
	config.InitConfig()
	cpuCount := viper.GetInt("environment.cpu-count")
	fmt.Println("当前CPU个数:", runtime.NumCPU())
	fmt.Println("占用CPU个数:", cpuCount)
	runtime.GOMAXPROCS(cpuCount)
	global.Logger = config.InitLogger()
	global.Logger.Info("日志框架初始化完成!")
	global.MysqlClient = config.InitMysql()
	global.Logger.Info("MYSQL框架初始化完成!")
	global.RedisClient = config.InitRedis()
	global.Logger.Info("REDIS框架初始化完成!")
	connection.InitConnectionManager()
	router.InitRouterManager()
	global.Logger.Info("连接管理者初始化完成!")
	game.InitGameManager()
	global.Logger.Info("游戏管理者初始化完成!")
	initGameHandler()
	http.HandleFunc("/diamond-battle-game", GameHandler)
	http.HandleFunc("/galaxy-escape-game", GameHandler)
	http.Handle("/", http.FileServer(http.Dir("./static/")))
	port := viper.GetString("game-server.port")
	err := http.ListenAndServe(":"+port, nil)
	if err != nil {
		global.Logger.Errorf("游戏服务启动失败!")
	}
	// testCase()
}

func initGameHandler() {
	router.RouterManagerInstance().AddRouter(proto.TEST, test.TestHandler)
	router.RouterManagerInstance().AddRouter(proto.HEART, heart.HeartHandler)
	router.RouterManagerInstance().AddRouter(proto.ROOMCONFIG, room.RoomConfigHandler)
	router.RouterManagerInstance().AddRouter(proto.ROOMJOIN, room.RoomJoinHandler)
	router.RouterManagerInstance().AddRouter(proto.ROOMEXIT, room.RoomExitHandler)
	router.RouterManagerInstance().AddRouter(proto.BET, bet.BetHandler)
	router.RouterManagerInstance().AddRouter(proto.AREACHANGE, change.AreaChangeHandler)
	router.RouterManagerInstance().AddRouter(proto.BarrageSend, barrage.BarrageHandler)
}

var Up = websocket.Upgrader{
	ReadBufferSize:  1024,
	WriteBufferSize: 1024,
	CheckOrigin:     func(request *http.Request) bool { return true },
}

func GameHandler(writer http.ResponseWriter, request *http.Request) {
	/*
		token := request.URL.Query().Get("authorization")


		if token == "" {
			writer.Write([]byte("token err!"))
			return
		}
		global.Logger.Infof("token:%v", token)
		queryPlayerUrl := viper.GetString("hall-server.url.query-player")
		headers := map[string][]string{}
		headers["Content-Type"] = []string{"application/json"}
		headers["token"] = []string{token}

			req := &netutil.HttpRequest{
				RawURL:  queryPlayerUrl,
				Method:  http.MethodPost,
				Headers: headers,
			}


				hallServerHttpRes, err := tool.HttpSendFunction(req)
				global.Logger.Infof("hallServerHttpRes:%v", convertor.ToString(hallServerHttpRes))
				if err != nil || hallServerHttpRes.Code != "0" {
					writer.Write([]byte("player err!"))
					return
				}
				playerInfoHttpResMap := hallServerHttpRes.Data.(map[string]interface{})
	*/

	playerInfoHttpResMap := make(map[string]interface{})
	playerInfoHttpResMap["id"] = "111111"
	playerInfoHttpResMap["diamondBalance"] = "1000000"
	playerInfoHttpResMap["userName"] = "test"
	playerInfoHttpResMap["winPercent"] = "100"
	playerInfoHttpResMap["level"] = "1"
	playerInfoHttpResMap["userType"] = "1"

	playerInfoHttpResMap["userCode"] = "123"

	playerId, err := convertor.ToInt(playerInfoHttpResMap["id"])
	if err != nil {
		writer.Write([]byte("player err!"))
		return
	}
	coins, err := convertor.ToInt(playerInfoHttpResMap["diamondBalance"])
	if err != nil {
		writer.Write([]byte("player err!"))
		return
	}
	nickName := convertor.ToString(playerInfoHttpResMap["userName"])
	winPercentStr := convertor.ToString(playerInfoHttpResMap["winPercent"])
	global.Logger.Infof("winPercentStr:%v", winPercentStr)
	winPercent := int64(0)
	if winPercentStr != "" {
		winPercentInt, _ := convertor.ToInt(winPercentStr)
		winPercent = winPercentInt
	}
	levelStr := convertor.ToString(playerInfoHttpResMap["level"])
	global.Logger.Infof("levelStr:%v", levelStr)
	level := int64(0)
	if levelStr != "" {
		levelInt, _ := convertor.ToInt(levelStr)
		level = levelInt
	}
	userTypeStr := convertor.ToString(playerInfoHttpResMap["userType"])
	global.Logger.Infof("userTypeStr:%v", userTypeStr)
	userType := model.NORMAL
	if userTypeStr != "" {
		userTypeInt, _ := convertor.ToInt(userTypeStr)
		userType = int(userTypeInt)
	}
	avatarStr := convertor.ToString(playerInfoHttpResMap["avatar"])
	global.Logger.Infof("avatarStr:%v", avatarStr)
	avatar := int64(0)
	if avatarStr != "" {
		avatarInt, _ := convertor.ToInt(avatarStr)
		avatar = avatarInt
	}
	userCode := convertor.ToString(playerInfoHttpResMap["userCode"])
	betState := 0
	betStateStr := convertor.ToString(playerInfoHttpResMap["betState"])
	if betStateStr != "" {
		betStateInt, _ := convertor.ToInt(betStateStr)
		betState = int(betStateInt)
	}
	//测试
	//playerId, _ := convertor.ToInt(request.URL.Query().Get("playerId"))
	//coins, _ := convertor.ToInt(request.URL.Query().Get("coins"))
	//nickName := request.URL.Query().Get("nickName")
	//winPercent, _ := convertor.ToInt(request.URL.Query().Get("winPercent"))
	//level, _ := convertor.ToInt(request.URL.Query().Get("level"))
	//avatar, _ := convertor.ToInt(request.URL.Query().Get("avatar"))
	//userCode := request.URL.Query().Get("userCode")
	//userTypeInt, _ := convertor.ToInt(request.URL.Query().Get("userType"))
	//userType := int(userTypeInt)
	//betStateInt, _ := convertor.ToInt(request.URL.Query().Get("betState"))
	//betState := int(betStateInt)
	//测试
	global.RedisClient.Del(context.Background(), viper.GetString("redis.weight-key")+convertor.ToString(playerId))
	isExists := global.RedisClient.Exists(context.Background(), viper.GetString("redis.player-key")+convertor.ToString(playerId)).Val()
	playerRd := global.RedisClient.Get(context.Background(), viper.GetString("redis.player-key")+convertor.ToString(playerId)).Val()
	playerRdInfo := &model.PlayerInfo{}
	json.Unmarshal([]byte(playerRd), playerRdInfo)
	var playerInfo *model.PlayerInfo = nil
	if isExists > 0 && playerRdInfo.IsGaming {
		playerInfo = &model.PlayerInfo{}
		convertor.CopyProperties(playerInfo, playerRdInfo)
		playerInfo.Id = playerId
		playerInfo.Coins = coins
		playerInfo.NickName = nickName
		playerInfo.Avatar = avatar
		playerInfo.UserCode = userCode
		playerInfo.WinPercent = winPercent
		playerInfo.Level = level
		playerInfo.UserType = userType
		playerInfo.BetState = betState
		connectionWrapper := connection.ConnectionManagerInstance().QueryConnOne(playerId)
		global.Logger.Infof("connectionWrapper:%v", connectionWrapper)
		if connectionWrapper != nil {
			global.Logger.Infof("断开连接ID:%v", connectionWrapper.UserId)
			messageWrapper := &message.MessageWrapper{
				Code: proto.OFFLINE,
				Data: nil,
			}
			connectionWrapper.Receive(messageWrapper)
			time.Sleep(1 * time.Second)
			connection.ConnectionManagerInstance().RemoveConn(playerId)
		}
	} else {
		playerInfo = &model.PlayerInfo{
			Id:               playerId,
			NickName:         nickName,
			Avatar:           avatar,
			UserCode:         userCode,
			Coins:            coins,
			WinPercent:       winPercent,
			Level:            level,
			UserType:         userType,
			BetState:         betState,
			LastBetTimeStamp: tool.CurrentTimestamp(),
			IsGaming:         false,
			IsRobot:          false,
		}
	}
	jsonStr, _ := convertor.ToJson(playerInfo)
	tokenTime := viper.GetInt("redis.token-time")
	global.RedisClient.Set(context.Background(), viper.GetString("redis.player-key")+convertor.ToString(playerInfo.Id), jsonStr, time.Duration(tokenTime)*time.Minute)
	conn, err := Up.Upgrade(writer, request, nil)
	if err != nil {
		global.Logger.Errorf("err:%v", err)
		global.Logger.Errorf("websocket connection err!")
		//conn.Close()
		return
	}
	connectionWrapper := &connection.ConnectionWrapper{UserId: playerInfo.Id, Conn: conn}
	connection.ConnectionManagerInstance().AddConn(playerInfo.Id, connectionWrapper)
	global.Logger.Infof("userId:%v,昵称:%v,金币:%v,等级:%v,胜率:%v,头像:%v,类型:%v,加入游戏!", playerInfo.Id, playerInfo.NickName, playerInfo.Coins, playerInfo.Level, playerInfo.WinPercent, playerInfo.Avatar, playerInfo.UserType)
	connectionWrapper.ConnectionWrapperInitialize()
	playerInfoRes := proto.PlayerInfoRes{IsSelf: true}
	convertor.CopyProperties(&playerInfoRes, playerInfo)
	messageWrapper := message.MessageWrapper{
		Code: proto.PLAYERINFO,
		Data: playerInfoRes,
	}
	connectionWrapper.Receive(&messageWrapper)
	if playerInfo.IsGaming {
		roomInfo := game.GameManagerInstance().QueryRoomInfo(playerInfo.Id)
		if roomInfo != nil {
			roomInfo.SynRoomInfo()
			roomInfo.SynPlayerInfo()
			roomInfo.SynBetInfo()
			roomInfo.SynPrizeInfo()
		}
	}
}

func testCase() {
	//data := "KGm76H2dSYw6y/nALtid/2TF7kZ1+1PpjW63qXFcblleQbu5Xe0TxXXatewCosOoslHM5A3L+0Jq04dvvlDxaGlG6f7WlUbIDMgGz9UvksKzO4dJQovpiCGiZFnaMAcUg2UfzhYLoO7larz9Ej9RUTvDM4C7+BD0Ps0r4ndx6L+6J+hjRo68j6bf8IBXCS1DUyhVNEuynfxsO/alg2aNUZnzveSknKeMRmyGU7UXwIk="
	//key := "JaAHJWWd"
	////encrypted := cryptor.DesEcbEncrypt([]byte(data), []byte(key))
	//decodeString, _ := base64.StdEncoding.DecodeString(data)
	//decrypted := cryptor.DesEcbDecrypt(decodeString, []byte(key))
	////fmt.Println("encrypted:", base64.StdEncoding.EncodeToString(encrypted))
	//fmt.Println("decrypted:", string(decrypted))

	//redisKey := viper.GetString("redis.weight-key") + "452"
	//result, _ := global.RedisClient.Exists(context.Background(), redisKey).Result()
	//if result > 0 {
	//	weightInfo := make(map[string]float64)
	//	data, _ := global.RedisClient.Get(context.Background(), redisKey).Result()
	//	global.Logger.Infof("data:%v", data)
	//	err := json.Unmarshal([]byte(data), &weightInfo)
	//	if err != nil {
	//		global.Logger.Infof("err:%v", err)
	//	}
	//	weight, err := convertor.ToInt(weightInfo["winPercent"])
	//	if err != nil {
	//		global.Logger.Infof("err:%v", err)
	//	}
	//	global.Logger.Infof("winPercent:%v", weight)
	//}

	//element := 5
	//list := make([]int, 0)
	//list = append(list, 1)
	//list = append(list, 2)
	//list = append(list, 3)
	//list = append(list, 4)
	//fmt.Printf("list:%v", list)
	//index := -1
	//for k, v := range list {
	//	if v == element {
	//		index = k
	//	}
	//}
	//if index != -1 {
	//	list = append(list[:index], list[index+1:]...)
	//}
	//fmt.Printf("list:%v", list)
	//fmt.Printf("index:%v", index)

	global.RedisClient.Incr(context.Background(), viper.GetString("player-settle-count")+"111111")
}
